package notify

import (
	"fmt"
	"strings"
	"unicode"

	"github.com/mattn/go-runewidth"
)

// MessageBox is used to draw a message box
type MessageBox struct {
	msgs  []string
	width int
}

// NewMessageBox creates a new message box instance.
// The width is 72 by default, making it suitable for the most popular 80
// columns terminal(git would attach an 8 width prefix 'remote: ').
func NewMessageBox(sampleWidth int) *MessageBox {
	width := sampleWidth
	if width < 72 {
		width = 72
	}
	return &MessageBox{
		msgs:  make([]string, 0, 2),
		width: width,
	}
}

// Addf messages to message box
func (v *MessageBox) Addf(format string, a ...interface{}) {
	msg := fmt.Sprintf(format, a...)
	for _, line := range strings.Split(msg, "\n") {
		v.addLine(strings.TrimRightFunc(line, unicode.IsSpace))
	}
}

func (v *MessageBox) addLine(line string) {
	rawWidth := runewidth.StringWidth(line)
	if rawWidth <= v.width {
		v.msgs = append(v.msgs, line)
		return
	}

	currentWidth := 0
	currentMsg := []rune{}
	for _, r := range line {
		tmpWidth := currentWidth + runewidth.RuneWidth(r)
		if tmpWidth < v.width {
			currentWidth = tmpWidth
			currentMsg = append(currentMsg, r)
		} else if tmpWidth == v.width {
			currentMsg = append(currentMsg, r)
			v.msgs = append(v.msgs, string(currentMsg))
			currentMsg = []rune{}
			currentWidth = 0
		} else {
			v.msgs = append(v.msgs, string(currentMsg))
			currentMsg = []rune{r}
			currentWidth = tmpWidth - currentWidth
		}
	}
	if len(currentMsg) > 0 {
		v.msgs = append(v.msgs, string(currentMsg))
	}
}

// GetNotify returns messages processed by message box
func (v *MessageBox) GetNotify() string {
	return strings.Join(v.msgs, "\n")
}
